<?php

namespace App\Repository;

use App\Exceptions\BusinessException;
use App\Common\Constant;
use App\Common\ResponseCode;
use App\Models\Base\Files;
use App\Models\Customer\Address;
use App\Models\Goods\AttributesValue;
use App\Models\Goods\FileBind;
use App\Models\Goods\Goods;
use App\Models\Goods\Products;
use App\Models\Role\Role;
use App\Models\Sales\Delivery;
use App\Models\Sales\DeliveryCompany;
use App\Models\Sales\DeliveryItem;
use App\Models\Sales\OrderItems;
use App\Models\Sales\Orders;
use App\Models\User\User;
use App\Params\Backend\DeliveryCompanyListParams;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

/**
 * 发货单数据仓储类
 *
 * @package App\Http\Repository
 * @author WangBin
 * @mail: <849850352@qq.com>
 */
class DeliveryRepository extends BaseRepository
{
    /**
     * 获取发货单
     *
     * @param int $orderId
     * @return int|mixed
     */
    public function getByOrderId(int $orderId)
    {
        return Delivery::query()->where('order_id', $orderId)->first();
    }

    /**
     * 根据 Id 获取发货单
     *
     * @param int $deliveryId
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
     */
    public function getById(int $deliveryId)
    {
        return Delivery::query()->where('delivery_id', $deliveryId)->first();
    }

    /**
     * 根据物流编号获取发货单
     *
     * @param string $expressBn
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
     */
    public function getByExpressBn(string $expressBn)
    {
        return Delivery::query()->where('express_bn', $expressBn)->first();
    }

    /**
     * 校验物流单号唯一
     *
     * @param string $expressBn
     * @param int $deliveryId
     * @return bool
     */
    public function checkExpressBnUnique(string $expressBn, int $deliveryId = 0)
    {
        $query = Delivery::query()->where('express_bn', $expressBn);
        if($deliveryId) {
            $query->where('delivery_id', '!=', $deliveryId);
        }
        return $query->exists();
    }

    /**
     * 根据 Id 查询物流公司
     *
     * @param int $companyId
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
     */
    public function getCompany(int $companyId)
    {
        return DeliveryCompany::query()->where('company_id', $companyId)->first();
    }

    /**
     * 保存发货单
     *
     * @param array $data
     * @param int $deliveryId
     * @return int|mixed
     * @throws \Exception
     */
    public function create(array $data)
    {
        $query = new Delivery();
        foreach ($data as $field => $value) {
            $query->{$field} = $value;
        }
        return $query->save();
    }

    /**
     * 保存发货单明细
     *
     * @param array $items
     * @param int $deliveryId
     * @return int|mixed
     * @throws \Exception
     */
    public function updateItems(array $items, int $deliveryId = 0)
    {
        try {
            $result = 0;
            foreach ($items as $item) {
                $deliveryItem = $this->getItemByDeliveryAndProduct($deliveryId, $item['product_id']);
                if(is_null($deliveryItem)) {
                    $deliveryItem = new DeliveryItem();
                }
                foreach ($item as $field => $value) {
                    $deliveryItem->{$field} = $value;
                }
                $deliveryItemId = $deliveryItem->save();
                if(!$deliveryItemId) {
                    throw new \Exception('保存发货单明细失败');
                }
                $result += 1;
            }
            return $result == count($items);
        } catch (\Exception $exception) {
            throw new \Exception($exception->getMessage());
        }
    }

    /**
     * 根据发货单 Id、商品 Id 获取发货明细
     *
     * @param int $deliveryId
     * @param int $productId
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
     */
    public function getItemByDeliveryAndProduct(int $deliveryId, int $productId)
    {
        return DeliveryItem::query()->where('delivery_id', $deliveryId)->where('product_id', $productId)->first();
    }

    /**
     * 获取物流公司列表
     *
     * @param array $filter
     * @return
     */
    public function getCompanyList(array $filter = [])
    {
        $query = DeliveryCompany::query();
        if(!empty($filter['company_bn'])) {
            $query->where('company_bn', $filter['company_bn']);
        }
        if(!empty($filter['name'])) {
            $query->where('name', 'like', '%' . $filter['name'] . '%');
        }
        return $query;
    }

    /**
     * 获取发货单列表
     *
     * @param array $filter
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function getList(array $filter = [])
    {
        $query = Delivery::query()->orderByDesc('created_at');
        if(!empty($filter['delivery_bn'])) {
            $query->where('delivery_bn', $filter['delivery_bn']);
        }
        if(!empty($filter['customer_name'])) {
            $query->where('customer_name', $filter['customer_name']);
        }
        if(!empty($filter['order_bn'])) {
            $query->where('order_bn', $filter['order_bn']);
        }
        if(!empty($filter['start_at'])) {
            $query->where('created_at', '>=', $filter['start_at']);
        }
        if(!empty($filter['end_at'])) {
            $query->where('created_at', '<=', $filter['end_at']);
        }
        return $query;
    }

    /**
     * 获取发货单明细
     *
     * @param int $deliveryId
     * @return \Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection
     */
    public function getItems(int $deliveryId)
    {
        return DeliveryItem::query()->where('delivery_id', $deliveryId)->get();
    }

    /**
     * 获取发货单详细信息
     *
     * @param int $deliveryId
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
     */
    public function getDeliveryInfo(int $deliveryId)
    {
        $delivery = $this->getById($deliveryId);
        $delivery->items = $this->getItems($deliveryId);
        return $delivery;
    }
}
